<html>
<head><meta charset="utf-8"><title>Unsafe const fn? · t-compiler/const-eval · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/index.html">t-compiler/const-eval</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html">Unsafe const fn?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="212386087"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212386087" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212386087">(Oct 06 2020 at 05:23)</a>:</h4>
<p>While reading <a href="https://github.com/rust-lang/rust/issues/49146#issuecomment-616301045">https://github.com/rust-lang/rust/issues/49146#issuecomment-616301045</a> and issues like <a href="https://github.com/rust-lang/rust/issues/66753">https://github.com/rust-lang/rust/issues/66753</a> it occurred to me that <code>const fn</code> requires some very nontrivial static analysis, and because the properties in question are in general undecidable we will never be entirely happy with what is accepted and what isn't. But the story of the borrow checker is basically the same, and there we have an alternative: <code>unsafe</code>. So where is <code>unsafe const fn</code>? That is, it should be possible to assert that a function is valid in const context and will not trip up CTFE after monomorphization, even though the current incarnation of the static analysis cannot prove this.</p>



<a name="212386213"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212386213" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212386213">(Oct 06 2020 at 05:26)</a>:</h4>
<p>(The terminology <code>unsafe const fn</code> is not the best here, as that already means something, namely a function which is unsafe and a <code>const fn</code>. I really mean <code>(unsafe const) fn</code>, i.e. the fact that this fn is const is asserted by the programmer.)</p>



<a name="212386317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212386317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212386317">(Oct 06 2020 at 05:28)</a>:</h4>
<p>It's also arguably not even unsafe, since any errors will still be caught at compile time, but it might be only after compiling a downstream crate.</p>



<a name="212388487"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212388487" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212388487">(Oct 06 2020 at 06:17)</a>:</h4>
<p>We've discussed this before, and I think we should be able to do everything with my proposal in <a href="https://github.com/rust-lang/const-eval/issues/7#issuecomment-576243335">https://github.com/rust-lang/const-eval/issues/7#issuecomment-576243335</a></p>



<a name="212390747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212390747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212390747">(Oct 06 2020 at 06:58)</a>:</h4>
<p>Thanks for the pointer, that's an interesting primitive. (It's not clear to me if you are asserting this, but:) I don't think it's complete for all the things that <code>unsafe const</code> could do. For example you could have a function which is <em>in fact</em> const under all possible ways to call it, even though it contains non-const-safe code in it, maybe because of language rules (e.g. drop calls), which will not be executed.</p>



<a name="212391552"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212391552" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212391552">(Oct 06 2020 at 07:10)</a>:</h4>
<p>I suppose your claim is that if we are in a const-only context (as we would be if you are writing the const part of a selection) then it's always possible to write the code such that any const-unsafe code path is replaced with <code>unreachable!()</code>? (Then again perhaps even <code>unreachable!()</code> is const unsafe.)</p>



<a name="212397329"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212397329" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212397329">(Oct 06 2020 at 08:21)</a>:</h4>
<p><code>unreachable!()</code> is not const unsafe, in fact, it works with just a single feature gate whose sole blocking issue is that we haven't finished the discussion on the diagnostic message <span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span></p>



<a name="212397369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212397369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212397369">(Oct 06 2020 at 08:21)</a>:</h4>
<p>Yes, my assertion is that if the code is unreachable, then it should be marked as such. Also you can always work around drop impls missing by invoking <code>mem::forget</code></p>



<a name="212397691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212397691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212397691">(Oct 06 2020 at 08:25)</a>:</h4>
<p>Basically the reason I don't want a feature like you're describing it (essentially C++'s <code>constexpr</code>) is that the implementation of  the static analysis permitting such a feature is inherently incompatible with the static checks that we have for <code>const fn</code>, because our checks are not happening on a syntactical basis, but on the MIR, which is a control flow graph disconnected from the original syntax. unsafety checks do the same thing, but it works for them, because there's a whole system built around unsafety that handles this. I don't think the small wins in expressiveness are worth another (orthogonal) safety analysis, if there is a trivial alternative like the one I proposed</p>



<a name="212397813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212397813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212397813">(Oct 06 2020 at 08:26)</a>:</h4>
<p>That said, we have the feature you are asking for under the perma-forever-unstable feature gate <code>-Zunleash-the-miri-inside-of-you</code></p>



<a name="212397882"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Unsafe%20const%20fn%3F/near/212397882" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Unsafe.20const.20fn.3F.html#212397882">(Oct 06 2020 at 08:27)</a>:</h4>
<p>But that enables this for all constants and <code>const fn</code> within the crate being compiled and will absolutely void your warranty <span aria-label="tm" class="emoji emoji-2122" role="img" title="tm">:tm:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>